package com.cuixichang.minimalism.controller;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cuixichang.minimalism.acl.SubassemblyDesignAbs;
import com.cuixichang.minimalism.basal.base.Result;
import com.cuixichang.minimalism.basal.core.RelationDict;
import com.cuixichang.minimalism.basal.core.SubassemblyRelationDict;
import com.cuixichang.minimalism.core.security.userdetails.CredentialDetail;
import com.cuixichang.minimalism.core.security.utils.SecurityBeanUtil;
import com.cuixichang.minimalism.domain.IFormCommandService;
import com.cuixichang.minimalism.domain.IFormValueCommandService;
import com.cuixichang.minimalism.transfer.dto.IFormDTO;
import com.cuixichang.minimalism.transfer.factory.IFormAssembler;
import com.cuixichang.minimalism.transfer.page.IFormPageRequest;
import com.cuixichang.minimalism.transfer.page.IFormQueryRequest;
import com.cuixichang.minimalism.transfer.page.IFormRequest;
import com.cuixichang.minimalism.transfer.vo.IFormVO;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import com.cuixichang.minimalism.service.IFormService;
import org.springframework.beans.factory.annotation.Autowired;
import io.swagger.annotations.Api;
import lombok.RequiredArgsConstructor;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 拓展表单功能表表控制层
 *
 * @author cuixichang
 * @date 2024-12-15
 */
@Api(tags = "拓展表单功能表对象功能接口")
@RestController
@RequestMapping("form")
@RequiredArgsConstructor
public class IFormController {

    @Autowired
    private IFormService iFormService;
    @Autowired
    private IFormCommandService formCommandService;
    @Autowired
    private List<SubassemblyDesignAbs> subassemblyDesigns;
    @Autowired
    private IFormValueCommandService formValueCommandService;

    @GetMapping("/modules/{systemCode}")
    @ApiOperation(value = "查询表单分组信息")
    public Result<List<String>> getFormModules(@PathVariable String systemCode){
        return Result.ok("查询表单分组信息完成",formCommandService.getFormModules(systemCode));
    }

    @GetMapping("/moduleTypes")
    @ApiOperation(value = "查询表单类型信息")
    public Result<List<SubassemblyRelationDict>> getFormModuleTypes(){
        return Result.ok("查询表单分组信息完成", subassemblyDesigns.stream()
                .sorted(Comparator.comparing(design->design.getType().getKey()))
                .map(design-> SubassemblyRelationDict.builder().key(design.getType().getKey()).value(design.getType().getValue())
                        .example(design.example()).build()));
    }

    @GetMapping("/plugs/{systemCode}/{moduleName}/{fieldType}")
    @ApiOperation(value = "查询模块可用插件集合")
    public Result<List<RelationDict>> getFormPlugs(@PathVariable String systemCode,
                                                   @PathVariable String moduleName,
                                                   @PathVariable String fieldType,
                                                   Long formId){
        Optional<SubassemblyDesignAbs> first = subassemblyDesigns.stream().filter(subassembly -> subassembly.getType().getKey().equals(fieldType))
                .findFirst();
        List<RelationDict> result = Collections.EMPTY_LIST;
        if(first.isPresent()){
            SubassemblyDesignAbs subassemblyDesignAbs = first.get();
            result = subassemblyDesignAbs.getApplicationBindingPlug(systemCode, moduleName, fieldType,formId);
        }
        return Result.ok("查询模块可用插件集合信息完成", result);
    }

    @PostMapping("/info")
    @ApiOperation(value = "创建表单基本信息")
    public Result<IFormVO> insert(@RequestBody IFormRequest request) {
        IFormDTO dto = IFormAssembler.INSTANCT.convertDto(request);
        IFormDTO insert = formCommandService.insert(dto,SecurityBeanUtil.getCredentialDetail());
        return Result.ok("创建表单基本信息成功", IFormAssembler.INSTANCT.convertVo(insert));
    }

    @DeleteMapping("/info/{systemCode}/{id}")
    @ApiOperation(value = "删除表单字段基本信息通过ID")
    public Result<Boolean> deleteById(@PathVariable Long id, @PathVariable("systemCode") String systemCode){
        return Result.ok("删除表单字段基本信息完成", formCommandService.deleteById(id,systemCode));
    }

    @GetMapping("/info/{systemCode}/{id}")
    @ApiOperation(value = "查询表单字段基本信息通过ID")
    public Result<IFormVO> selectById(@PathVariable("id") Long id, @PathVariable("systemCode") String systemCode){
        IFormDTO form = formCommandService.selectByIdHasPreCheck(id, systemCode);
        return Result.ok("查询菜单基本信息完成", IFormAssembler.INSTANCT.convertVo(form));
    }

    @PutMapping("/info/{systemCode}/{id}")
    @ApiOperation(value = "编辑表单字段基本信息通过ID")
    public Result<Boolean> updateById(@PathVariable Long id,
                                      @PathVariable("systemCode") String systemCode,
                                      @RequestBody IFormRequest request){
        IFormDTO dto = IFormAssembler.INSTANCT.convertDto(request);
        dto.setId(id);
        dto.setCreateSystemCode(systemCode);
        return Result.ok("编辑表单字段基本信息完成",formCommandService.updateById(dto,SecurityBeanUtil.getCredentialDetail()));
    }

    @GetMapping("/page")
    @ApiOperation(value = "查询用户可操作的表单字段信息")
    public Result<Page<IFormVO>> searchPageByConditional(IFormPageRequest request){
        IFormDTO dto = IFormAssembler.INSTANCT.convertDto(request);
        Page<IFormDTO> page = formCommandService.searchPageByConditional(dto, request.getPageNo(), request.getPageSize());
        Page<IFormVO> voPage = new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
        List<IFormDTO> records = page.getRecords();
        voPage.setRecords(records.stream().map(IFormAssembler.INSTANCT::convertVo).collect(Collectors.toList()));
        return Result.ok("查询用户可操作的表单字段信息完成",voPage);
    }

    @GetMapping("/fields/{systemCode}/{moduleName}")
    @ApiOperation(value = "查询表单字段列表")
    public Result<List<IFormVO>> searchFieldsByModuleName( @PathVariable("systemCode") String systemCode,
                                                           @PathVariable("moduleName") String moduleName,
                                                           IFormQueryRequest request){
        IFormDTO dto = IFormAssembler.INSTANCT.convertDto(request);
        dto.setModuleName(moduleName);
        dto.setCreateSystemCode(systemCode);
        List<IFormDTO> fieds = formCommandService.searchFieldsByModuleName(dto,request.getLoginId());
        List<IFormVO> results = fieds.stream().map(IFormAssembler.INSTANCT::convertVo).collect(Collectors.toList());
        return Result.ok("查询表单字段列表信息完成",results);
    }

    @GetMapping("/preview/{systemCode}/{moduleName}/{plugName}")
    public Result<String> getFormPreviewValue(@PathVariable String systemCode,
                                              @PathVariable String moduleName,
                                              @PathVariable String plugName){
        CredentialDetail credentialDetail = SecurityBeanUtil.getCredentialDetail();
        String result = Objects.nonNull(credentialDetail) ? formValueCommandService.getValue(systemCode, moduleName, plugName,
                String.valueOf(credentialDetail.getLoginId())) : StrUtil.EMPTY;
        return Result.ok("查询表单字段存储值完成",result);
    }
}
